{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Infinite Iterators"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There are three functions in the `itertools` module that produce infinite iterators: `count`, `cycle` and `repeat`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from itertools import (\n",
    "    count,\n",
    "    cycle,\n",
    "    repeat, \n",
    "    islice)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### count"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `count` function is similar to range, except it does not have a `stop` value. It has both a `start` and a `step`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "g = count(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[10, 11, 12, 13, 14]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(islice(g, 5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "g = count(10, step=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[10, 12, 14, 16, 18]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(islice(g, 5))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And so on. \n",
    "\n",
    "Unlike the `range` function, whose arguments must always be integers, `count` works with floats as well:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "g = count(10.5, 0.5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[10.5, 11.0, 11.5, 12.0, 12.5]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(islice(g, 5))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In fact, we can even use other data types as well:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "g = count(1+1j, 1+2j)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(1+1j), (2+3j), (3+5j), (4+7j), (5+9j)]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(islice(g, 5))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can even use Decimal numbers:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from decimal import Decimal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "g = count(Decimal('0.0'), Decimal('0.1'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Decimal('0.0'),\n",
       " Decimal('0.1'),\n",
       " Decimal('0.2'),\n",
       " Decimal('0.3'),\n",
       " Decimal('0.4')]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(islice(g, 5))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Cycle"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`cycle` is used to repeatedly loop over an iterable:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "g = cycle(('red', 'green', 'blue'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['red', 'green', 'blue', 'red', 'green', 'blue', 'red', 'green']"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(islice(g, 8))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "One thing to note is that this works **even** if the argument is an iterator (i.e. gets exhausted after the first complete iteration over it)!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's see a simple example of this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def colors():\n",
    "    yield 'red'\n",
    "    yield 'green'\n",
    "    yield 'blue'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "cols = colors()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['red', 'green', 'blue']"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(cols)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[]"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(cols)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As expected, `cols` was exhausted after the first iteration.\n",
    "\n",
    "Now let's see how `cycle` behaves:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "cols = colors()\n",
    "g = cycle(cols)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['red', 'green', 'blue', 'red', 'green', 'blue', 'red', 'green', 'blue', 'red']"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(islice(g, 10))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As you can see, `cycle` iterated over the elements of iterator, and continued the iteration even though the first run through the iterator technically exhausted it."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Example"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A simple application of `cycle` is dealing a deck of cards into separate hands:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from collections import namedtuple"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "Card = namedtuple('Card', 'rank suit')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def card_deck():\n",
    "    ranks = tuple(str(num) for num in range(2, 11)) + tuple('JQKA')\n",
    "    suits = ('Spades', 'Hearts', 'Diamonds', 'Clubs')\n",
    "    for suit in suits:\n",
    "        for rank in ranks:\n",
    "            yield Card(rank, suit)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Assume we want 4 hands, so we can think of the hands as a list containing 4 elements - each of which is itself a list containing cards.\n",
    "\n",
    "The indices of the hands would be `0, 1, 2, 3` in the hands list:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We could certainly do it this way:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "hands = [list() for _ in range(4)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[], [], [], []]"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hands"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "index = 0\n",
    "for card in card_deck():\n",
    "    index = index % 4\n",
    "    hands[index].append(card)\n",
    "    index += 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[Card(rank='2', suit='Spades'),\n",
       "  Card(rank='6', suit='Spades'),\n",
       "  Card(rank='10', suit='Spades'),\n",
       "  Card(rank='A', suit='Spades'),\n",
       "  Card(rank='5', suit='Hearts'),\n",
       "  Card(rank='9', suit='Hearts'),\n",
       "  Card(rank='K', suit='Hearts'),\n",
       "  Card(rank='4', suit='Diamonds'),\n",
       "  Card(rank='8', suit='Diamonds'),\n",
       "  Card(rank='Q', suit='Diamonds'),\n",
       "  Card(rank='3', suit='Clubs'),\n",
       "  Card(rank='7', suit='Clubs'),\n",
       "  Card(rank='J', suit='Clubs')],\n",
       " [Card(rank='3', suit='Spades'),\n",
       "  Card(rank='7', suit='Spades'),\n",
       "  Card(rank='J', suit='Spades'),\n",
       "  Card(rank='2', suit='Hearts'),\n",
       "  Card(rank='6', suit='Hearts'),\n",
       "  Card(rank='10', suit='Hearts'),\n",
       "  Card(rank='A', suit='Hearts'),\n",
       "  Card(rank='5', suit='Diamonds'),\n",
       "  Card(rank='9', suit='Diamonds'),\n",
       "  Card(rank='K', suit='Diamonds'),\n",
       "  Card(rank='4', suit='Clubs'),\n",
       "  Card(rank='8', suit='Clubs'),\n",
       "  Card(rank='Q', suit='Clubs')],\n",
       " [Card(rank='4', suit='Spades'),\n",
       "  Card(rank='8', suit='Spades'),\n",
       "  Card(rank='Q', suit='Spades'),\n",
       "  Card(rank='3', suit='Hearts'),\n",
       "  Card(rank='7', suit='Hearts'),\n",
       "  Card(rank='J', suit='Hearts'),\n",
       "  Card(rank='2', suit='Diamonds'),\n",
       "  Card(rank='6', suit='Diamonds'),\n",
       "  Card(rank='10', suit='Diamonds'),\n",
       "  Card(rank='A', suit='Diamonds'),\n",
       "  Card(rank='5', suit='Clubs'),\n",
       "  Card(rank='9', suit='Clubs'),\n",
       "  Card(rank='K', suit='Clubs')],\n",
       " [Card(rank='5', suit='Spades'),\n",
       "  Card(rank='9', suit='Spades'),\n",
       "  Card(rank='K', suit='Spades'),\n",
       "  Card(rank='4', suit='Hearts'),\n",
       "  Card(rank='8', suit='Hearts'),\n",
       "  Card(rank='Q', suit='Hearts'),\n",
       "  Card(rank='3', suit='Diamonds'),\n",
       "  Card(rank='7', suit='Diamonds'),\n",
       "  Card(rank='J', suit='Diamonds'),\n",
       "  Card(rank='2', suit='Clubs'),\n",
       "  Card(rank='6', suit='Clubs'),\n",
       "  Card(rank='10', suit='Clubs'),\n",
       "  Card(rank='A', suit='Clubs')]]"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hands"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You notice how we had to use the `mod` operator and an `index` to **cycle** through the hands.\n",
    "\n",
    "So, we can use the `cycle` function instead:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "hands = [list() for _ in range(4)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "index_cycle = cycle([0, 1, 2, 3])\n",
    "for card in card_deck():\n",
    "    hands[next(index_cycle)].append(card)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[Card(rank='2', suit='Spades'),\n",
       "  Card(rank='6', suit='Spades'),\n",
       "  Card(rank='10', suit='Spades'),\n",
       "  Card(rank='A', suit='Spades'),\n",
       "  Card(rank='5', suit='Hearts'),\n",
       "  Card(rank='9', suit='Hearts'),\n",
       "  Card(rank='K', suit='Hearts'),\n",
       "  Card(rank='4', suit='Diamonds'),\n",
       "  Card(rank='8', suit='Diamonds'),\n",
       "  Card(rank='Q', suit='Diamonds'),\n",
       "  Card(rank='3', suit='Clubs'),\n",
       "  Card(rank='7', suit='Clubs'),\n",
       "  Card(rank='J', suit='Clubs')],\n",
       " [Card(rank='3', suit='Spades'),\n",
       "  Card(rank='7', suit='Spades'),\n",
       "  Card(rank='J', suit='Spades'),\n",
       "  Card(rank='2', suit='Hearts'),\n",
       "  Card(rank='6', suit='Hearts'),\n",
       "  Card(rank='10', suit='Hearts'),\n",
       "  Card(rank='A', suit='Hearts'),\n",
       "  Card(rank='5', suit='Diamonds'),\n",
       "  Card(rank='9', suit='Diamonds'),\n",
       "  Card(rank='K', suit='Diamonds'),\n",
       "  Card(rank='4', suit='Clubs'),\n",
       "  Card(rank='8', suit='Clubs'),\n",
       "  Card(rank='Q', suit='Clubs')],\n",
       " [Card(rank='4', suit='Spades'),\n",
       "  Card(rank='8', suit='Spades'),\n",
       "  Card(rank='Q', suit='Spades'),\n",
       "  Card(rank='3', suit='Hearts'),\n",
       "  Card(rank='7', suit='Hearts'),\n",
       "  Card(rank='J', suit='Hearts'),\n",
       "  Card(rank='2', suit='Diamonds'),\n",
       "  Card(rank='6', suit='Diamonds'),\n",
       "  Card(rank='10', suit='Diamonds'),\n",
       "  Card(rank='A', suit='Diamonds'),\n",
       "  Card(rank='5', suit='Clubs'),\n",
       "  Card(rank='9', suit='Clubs'),\n",
       "  Card(rank='K', suit='Clubs')],\n",
       " [Card(rank='5', suit='Spades'),\n",
       "  Card(rank='9', suit='Spades'),\n",
       "  Card(rank='K', suit='Spades'),\n",
       "  Card(rank='4', suit='Hearts'),\n",
       "  Card(rank='8', suit='Hearts'),\n",
       "  Card(rank='Q', suit='Hearts'),\n",
       "  Card(rank='3', suit='Diamonds'),\n",
       "  Card(rank='7', suit='Diamonds'),\n",
       "  Card(rank='J', suit='Diamonds'),\n",
       "  Card(rank='2', suit='Clubs'),\n",
       "  Card(rank='6', suit='Clubs'),\n",
       "  Card(rank='10', suit='Clubs'),\n",
       "  Card(rank='A', suit='Clubs')]]"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hands"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "But we really can simplify this even further - why are we cycling through the indices? Why not simply cycle through the hand themselves, and append the card to the hands?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "hands = [list() for _ in range(4)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "hands_cycle = cycle(hands)\n",
    "for card in card_deck():\n",
    "    next(hands_cycle).append(card)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[Card(rank='2', suit='Spades'),\n",
       "  Card(rank='6', suit='Spades'),\n",
       "  Card(rank='10', suit='Spades'),\n",
       "  Card(rank='A', suit='Spades'),\n",
       "  Card(rank='5', suit='Hearts'),\n",
       "  Card(rank='9', suit='Hearts'),\n",
       "  Card(rank='K', suit='Hearts'),\n",
       "  Card(rank='4', suit='Diamonds'),\n",
       "  Card(rank='8', suit='Diamonds'),\n",
       "  Card(rank='Q', suit='Diamonds'),\n",
       "  Card(rank='3', suit='Clubs'),\n",
       "  Card(rank='7', suit='Clubs'),\n",
       "  Card(rank='J', suit='Clubs')],\n",
       " [Card(rank='3', suit='Spades'),\n",
       "  Card(rank='7', suit='Spades'),\n",
       "  Card(rank='J', suit='Spades'),\n",
       "  Card(rank='2', suit='Hearts'),\n",
       "  Card(rank='6', suit='Hearts'),\n",
       "  Card(rank='10', suit='Hearts'),\n",
       "  Card(rank='A', suit='Hearts'),\n",
       "  Card(rank='5', suit='Diamonds'),\n",
       "  Card(rank='9', suit='Diamonds'),\n",
       "  Card(rank='K', suit='Diamonds'),\n",
       "  Card(rank='4', suit='Clubs'),\n",
       "  Card(rank='8', suit='Clubs'),\n",
       "  Card(rank='Q', suit='Clubs')],\n",
       " [Card(rank='4', suit='Spades'),\n",
       "  Card(rank='8', suit='Spades'),\n",
       "  Card(rank='Q', suit='Spades'),\n",
       "  Card(rank='3', suit='Hearts'),\n",
       "  Card(rank='7', suit='Hearts'),\n",
       "  Card(rank='J', suit='Hearts'),\n",
       "  Card(rank='2', suit='Diamonds'),\n",
       "  Card(rank='6', suit='Diamonds'),\n",
       "  Card(rank='10', suit='Diamonds'),\n",
       "  Card(rank='A', suit='Diamonds'),\n",
       "  Card(rank='5', suit='Clubs'),\n",
       "  Card(rank='9', suit='Clubs'),\n",
       "  Card(rank='K', suit='Clubs')],\n",
       " [Card(rank='5', suit='Spades'),\n",
       "  Card(rank='9', suit='Spades'),\n",
       "  Card(rank='K', suit='Spades'),\n",
       "  Card(rank='4', suit='Hearts'),\n",
       "  Card(rank='8', suit='Hearts'),\n",
       "  Card(rank='Q', suit='Hearts'),\n",
       "  Card(rank='3', suit='Diamonds'),\n",
       "  Card(rank='7', suit='Diamonds'),\n",
       "  Card(rank='J', suit='Diamonds'),\n",
       "  Card(rank='2', suit='Clubs'),\n",
       "  Card(rank='6', suit='Clubs'),\n",
       "  Card(rank='10', suit='Clubs'),\n",
       "  Card(rank='A', suit='Clubs')]]"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hands"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Repeat"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `repeat` function is used to create an iterator that just returns the same value again and again. By default it is infinite, but a count can be specified optionally:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Python\n",
      "Python\n",
      "Python\n",
      "Python\n",
      "Python\n"
     ]
    }
   ],
   "source": [
    "g = repeat('Python')\n",
    "for _ in range(5):\n",
    "    print(next(g))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And we also optionally specify a count to make the iterator finite:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "g = repeat('Python', 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Python', 'Python', 'Python', 'Python']"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(g)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "The important thing to note as well, is that the \"value\" that is returned is the **same** object every time!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's see this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "l = [1, 2, 3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "result = list(repeat(l, 3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(True, True, True)"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l is result[0], l is result[1], l is result[2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "So be careful here. If you try to use repeat to create three separate instances of a list, you'll actually end up with shared references:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3], [1, 2, 3], [1, 2, 3])"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result[0], result[1], result[2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "result[0][0] = 100"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([100, 2, 3], [100, 2, 3], [100, 2, 3])"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result[0], result[1], result[2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you want to end up with three separate copies of your argument, then you'll need to use a copy mechanism (either shallow or deep depending on your needs).\n",
    "\n",
    "This is easily done using a comprehension expression:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "l = [1, 2, 3]\n",
    "result = [item[:] for item in repeat(l, 3)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(False, False, False)"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l is result[0], l is result[1], l is result[2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "result[0][0] = 100"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[100, 2, 3], [1, 2, 3], [1, 2, 3]]"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
